package autopeople.tools;

import java.io.File;

import javax.inject.Inject;
import javax.inject.Named;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import autopeople.domain.auto.Auto;
import autopeople.domain.auto.Engine;
import autopeople.domain.auto.WheelsType;
import autopeople.domain.auto.autotypes.Car;
import autopeople.domain.auto.autotypes.Motorbike;
import autopeople.domain.auto.autotypes.Trike;
import autopeople.service.AutoService;

@Named
public class AutoImporter {

	@Inject
	private AutoService autoService;

	public Document getNormalizedDocument(File file) throws Exception {

		final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		final DocumentBuilder db = dbf.newDocumentBuilder();

		final Document doc = db.parse(file);

		// The normalize operation is one that you typically use after making
		// modifications to a DOM, to ensure that the resulting DOM is as
		// compact
		// as possible.
		doc.getDocumentElement().normalize();

		return doc;
	}

	public void parseAndPersistAutosFromDocument(Document doc) {
		// Engine 'size' and Wheel 'type', all autos have got them
		final String[] elements = { "motorbike", "trike", "car" };
		for (final String element : elements) {
			final NodeList listOfElements = doc.getElementsByTagName(element);

			// do this for all <motorbike>, <trike> or <car> element in file
			for (int i = 0; i < listOfElements.getLength(); i++) {
				Engine engine = null;
				WheelsType wheelsType = null;

				final Node autoType = listOfElements.item(i);
				final NodeList autoTypeChildNodes = autoType.getChildNodes();
				for (int j = 0; j < autoTypeChildNodes.getLength(); j++) {
					final Node autoChildNode = autoTypeChildNodes.item(j);
					if ("engine".equals(autoChildNode.getNodeName())) {
						engine = new Engine(getAutoChildNodeValueForNodeName(
								autoChildNode, "engine", "size"));
					} else if ("wheels".equals(autoChildNode.getNodeName())) {
						wheelsType = WheelsType
								.getValue(getAutoChildNodeValueForNodeName(
										autoChildNode, "wheels", "type"));
					}
				}

				persistRetrievedAutos(autoType.getNodeName(), engine,
						wheelsType);
			}
		}
	}

	public void persistRetrievedAutos(String autoType, Engine engine,
			WheelsType wheelsType) {

		Auto newAuto = null;
		if ("car".equals(autoType)) {
			newAuto = new Car(engine, wheelsType);
			autoService.add(newAuto);
		} else if ("trike".equals(autoType)) {
			newAuto = new Trike(engine, wheelsType);
			autoService.add(newAuto);
		} else if ("motorbike".equals(autoType)) {
			newAuto = new Motorbike(engine, wheelsType);
			autoService.add(newAuto);
		}
	}

	public String getAutoChildNodeValueForNodeName(Node autoChildNode,
			String nodeName, String childNodeNameToFindValueOf) {
		final NodeList childNodes = autoChildNode.getChildNodes();
		for (int k = 0; k < childNodes.getLength(); k++) {
			final Node childNode = childNodes.item(k);
			if (childNodeNameToFindValueOf.equals(childNode.getNodeName())) {
				return childNode.getFirstChild().getNodeValue();
			}
		}
		return null;
	}
}
